home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
language
/
clisp_c.zoo
/
places.lsp
< prev
next >
Wrap
Lisp/Scheme
|
1993-06-05
|
44KB
|
910 lines
; CLISP - PLACES.LSP
; CLISP-spezifisch: string-concat, %rplaca, %rplacd, store, %setelt, ...
(in-package "SYSTEM")
;-------------------------------------------------------------------------------
; Funktionen zur Definition und zum Ausnutzen von places:
;-------------------------------------------------------------------------------
(defun get-setf-method-multiple-value (form &optional (env nil))
(do* ((newformbackup nil newform)
(newform form (macroexpand-1 newform env)))
((eq newformbackup newform)
(error #+DEUTSCH "Das Argument muß eine 'SETF-place' sein, ist aber keine: ~S"
#+ENGLISH "Argument ~S is not a SETF place."
#+FRANCAIS "L'argument ~S doit représenter une place modifiable."
newform
))
(when (symbolp newform)
(let ((storevar (gensym)))
(return (values nil
nil
`(,storevar)
`(SETQ ,newform ,storevar)
`,newform
) ) ) )
(when (and (consp newform) (symbolp (car newform)))
(let ((plist-info (get (first newform) 'SYSTEM::SETF-EXPANDER)))
(when plist-info
(if (symbolp plist-info) ; Symbol kommt von kurzem DEFSETF
(return
(do* ((storevar (gensym))
(tempvars nil (cons (gensym) tempvars))
(tempforms nil)
(formr (cdr newform) (cdr formr)))
((atom formr)
(setq tempforms (nreverse tempforms))
(values tempvars
tempforms
`(,storevar)
`(,plist-info ,@tempvars ,storevar)
`(,(first newform) ,@tempvars)
))
(setq tempforms (cons (car formr) tempforms))
) )
(let ((argcount (car plist-info)))
(if (eql argcount -5)
(return ; (-5 . fun) kommt von DEFINE-SETF-METHOD
(funcall (cdr plist-info) newform env)
)
(return ; (argcount . fun) kommt von langem DEFSETF
(let ((access-form newform)
(tempvars '())
(tempforms '())
(new-access-form '()))
(let ((i 0)) ; Argumente-Zähler
; argcount = -1 falls keine Keyword-Argumente existieren
; bzw. = Anzahl der einzelnen Argumente vor &KEY,
; = nil nachdem diese abgearbeitet sind.
(dolist (argform (cdr access-form))
(when (eql i argcount) (setf argcount nil i 0))
(if (and (null argcount) (evenp i))
(if (keywordp argform)
(push argform new-access-form)
(error #+DEUTSCH "Das Argument ~S zu ~S sollte ein Keyword sein."
#+ENGLISH "The argument ~S to ~S should be a keyword."
#+FRANCAIS "L'argument ~S de ~S doit être un mot-clé."
argform (car access-form)
) )
(let ((tempvar (gensym)))
(push tempvar tempvars)
(push argform tempforms)
(push tempvar new-access-form)
) )
(incf i)
) )
(setq new-access-form
(cons (car access-form) (nreverse new-access-form))
)
(let ((newval-var (gensym)))
(values
(nreverse tempvars)
(nreverse tempforms)
(list newval-var)
(funcall (cdr plist-info) new-access-form newval-var)
new-access-form
) ) ) ) ) )
) ) ) )
) )
;-------------------------------------------------------------------------------
(defun get-setf-method (form &optional (env nil))
(multiple-value-bind (vars vals stores store-form access-form)
(get-setf-method-multiple-value form env)
(unless (and (consp stores) (null (cdr stores)))
(error #+DEUTSCH "Diese 'SETF-place' produziert mehrere 'Store-Variable': ~S"
#+ENGLISH "SETF place ~S produces more than one store variable."
#+FRANCAIS "La place modifiable ~S produit plusieurs variables de résultat."
form
) )
(values vars vals stores store-form access-form)
) )
;-------------------------------------------------------------------------------
(defun documentation (symbol doctype)
(unless (symbolp symbol)
(error #+DEUTSCH "~S: Das ist als erstes Argument unzulässig, da kein Symbol: ~S"
#+ENGLISH "~S: first argument ~S is illegal, not a symbol"
#+FRANCAIS "~S : Le premier argument ~S est invalide car ce n'est pas un symbole."
'documentation symbol
) )
(getf (get symbol 'SYSTEM::DOCUMENTATION-STRINGS) doctype)
)
(defun SYSTEM::%SET-DOCUMENTATION (symbol doctype value)
(unless (symbolp symbol)
(error #+DEUTSCH "~S: Das ist als erstes Argument unzulässig, da kein Symbol: ~S"
#+ENGLISH "~S: first argument ~S is illegal, not a symbol"
#+FRANCAIS "~S : Le premier argument ~S est invalide car ce n'est pas un symbole."
'documentation symbol
) )
(if (null value)
(when (getf (get symbol 'SYSTEM::DOCUMENTATION-STRINGS) doctype)
(remf (get symbol 'SYSTEM::DOCUMENTATION-STRINGS) doctype)
)
(setf (getf (get symbol 'SYSTEM::DOCUMENTATION-STRINGS) doctype) value)
) )
;-------------------------------------------------------------------------------
(defmacro push (item place &environment env)
(if (symbolp place)
`(SETQ ,place (CONS ,item ,place))
(let ((itemvar (gensym)))
(multiple-value-bind (SM1 SM2 SM3 SM4 SM5) (get-setf-method place env)
(do* ((SM1r SM1 (cdr SM1r))
(SM2r SM2 (cdr SM2r))
(bindlist `((,itemvar ,item)) ))
((null SM1r)
(push `(,(first SM3) (CONS ,itemvar ,SM5)) bindlist)
`(LET* ,(nreverse bindlist)
,SM4
) )
(push `(,(first SM1r) ,(first SM2r)) bindlist)
) ) ) ) )
;-------------------------------------------------------------------------------
(defmacro define-setf-method (accessfn lambdalist &body body &environment env)
(unless (symbolp accessfn)
(error #+DEUTSCH "Der Name der Access-Function muß ein Symbol sein und nicht ~S."
#+ENGLISH "The name of the access function must be a symbol, not ~S"
#+FRANCAIS "Le nom de la fonction d'accès doit être un symbole et non ~S."
accessfn
) )
(multiple-value-bind (body-rest declarations docstring)
(system::parse-body body t env)
(if (null body-rest) (setq body-rest '(NIL)))
(let ((name (make-symbol (string-concat "SETF-" (symbol-name accessfn)))))
(multiple-value-bind (newlambdalist envvar) (remove-env-arg lambdalist name)
(let ((SYSTEM::%ARG-COUNT 0)
(SYSTEM::%MIN-ARGS 0)
(SYSTEM::%RESTP nil)
(SYSTEM::%LET-LIST nil)
(SYSTEM::%KEYWORD-TESTS nil)
(SYSTEM::%DEFAULT-FORM nil)
)
(SYSTEM::ANALYZE1 newlambdalist '(CDR SYSTEM::%LAMBDA-LIST)
name 'SYSTEM::%LAMBDA-LIST
)
(if (null newlambdalist)
(push `(IGNORE SYSTEM::%LAMBDA-LIST) declarations)
)
(let ((lengthtest (sys::make-length-test 'SYSTEM::%LAMBDA-LIST))
(mainform
`(LET* ,(nreverse SYSTEM::%LET-LIST)
,@(if declarations `(,(cons 'DECLARE declarations)))